/**
* @author Meng Zhang
**/

#pragma once

#include "../sxp/sxp.h"
#include "Config.h"

#include <string>

class EditColorsSerializer : public SXP::IPersistObj {
public:
	EditColors info;
public:
	EditColorsSerializer(){}
	EditColorsSerializer(EditColors _info) : info(_info){}

	static SXP::Tag tag_own,tag_item,tag_name,tag_rgb;

	SXP::Tag& GetClassTag() const { return tag_own; }
	static SXP::Tag& s_GetClassTag() {return tag_own; }

	void BeginElement(SXP::IParser *pIn, SXP::IElement *pElement) {}

	void EndElement(SXP::IParser *pIn, SXP::IElement *pElement) {
		if (pElement->IsA(tag_item))
			pElement->Retrieve(info.item);
		if (pElement->IsA(tag_name))
			pElement->Retrieve(info.name);
		if (pElement->IsA(tag_rgb))
			pElement->Retrieve(info.rgb);
	}

	void WriteElement(SXP::IOutStream *pOut, SXP::dict& attribs) {
		pOut->BeginObject(tag_own, attribs);
		pOut->WriteElement(tag_item,info.item);
		pOut->WriteElement(tag_name,info.name);
		pOut->WriteElement(tag_rgb,info.rgb);
		pOut->EndObject(tag_own);
	}
};

SXP::Tag EditColorsSerializer::tag_own("color");
SXP::Tag EditColorsSerializer::tag_name("name");
SXP::Tag EditColorsSerializer::tag_rgb("rgb");
SXP::Tag EditColorsSerializer::tag_item("item");


class ConfigInfoSerializer : public SXP::IPersistObj {
public:
	ConfigInfo info;
	std::vector<EditColorsSerializer*> pairs;

public:
	static SXP::Tag tag_Extension, tag_Font, tag_UseTabs , tag_Keywords, tag_CaretLineVisible , tag_CaretLineBack, tag_ForeColor, tag_BackColor , tag_CaretForeColor, tag_TabWidth, tag_Lexer , tag_TriggerChars;

	static SXP::Tag tag_Own;
	
	SXP::Tag& GetClassTag() const { return tag_Own; }
	void BeginElement(SXP::IParser *pIn, SXP::IElement *pElement) {
		if (pElement->IsA(EditColorsSerializer::s_GetClassTag())) {
			EditColorsSerializer *tmp = new EditColorsSerializer();
			pairs.push_back(tmp);
			pIn->ReadTo(tmp);
		}
	}

	void EndElement(SXP::IParser *pIn, SXP::IElement *pElement) {
		if (pElement->IsA(tag_Extension) ) {
			std::string tmp;
			pElement->Retrieve(tmp);
			info.Extension.push_back(tmp);
		}

		if( pElement->IsA(tag_Keywords) )   {
			KeyWords tmp;
			tmp.item = atol(pElement->Attrib("item"));
			//pElement->Retrieve(tmp.words);
			tmp.words = pElement->Attrib("words");
			info.Words.push_back(tmp);
		}

		if( pElement->IsA(tag_Font) )   pElement->Retrieve(info.Font);
		if( pElement->IsA(tag_UseTabs) )   pElement->Retrieve(info.UseTabs);
		if (pElement->IsA(tag_CaretLineVisible)) pElement->Retrieve(info.CaretLineVisible);
		if (pElement->IsA(tag_CaretLineBack)) pElement->Retrieve(info.CaretLineBack);
		if (pElement->IsA(tag_ForeColor)) pElement->Retrieve(info.ForeColor);
		if (pElement->IsA(tag_BackColor)) pElement->Retrieve(info.BackColor);
		if (pElement->IsA(tag_CaretForeColor)) pElement->Retrieve(info.CaretForeColor);
		if (pElement->IsA(tag_TabWidth)) pElement->Retrieve(info.TabWidth);
		if (pElement->IsA(tag_Lexer)) pElement->Retrieve(info.Lexer);
		if (pElement->IsA(tag_TriggerChars)) pElement->Retrieve(info.TriggerChars);
	}

	void WriteElement(SXP::IOutStream *pOut, SXP::dict& attribs) {
		// no attributes, don't add anything to attribs
		pOut->BeginObject(tag_Own, attribs);
		for (int i = 0;i<(int)info.Extension.size();++i)
			pOut->WriteElement(tag_Extension, info.Extension[i]);
		
		for (int i = 0;i<(int)info.Words.size();++i) {
			SXP::dict attr;
			char chID[10];
			ltoa( info.Words[i].item, chID, 10 );
			attr["item"] = chID;
			attr["words"] = info.Words[i].words;
			pOut->BeginObject(tag_Keywords,attr);
			pOut->EndObject(tag_Keywords);
		}

		pOut->WriteElement(tag_Font, info.Font);
		pOut->WriteElement(tag_UseTabs, info.UseTabs);
		pOut->WriteElement(tag_CaretLineVisible,info.CaretLineVisible);
		pOut->WriteElement(tag_CaretLineBack,info.CaretLineBack);
		pOut->WriteElement(tag_ForeColor,info.ForeColor);
		pOut->WriteElement(tag_BackColor,info.BackColor);
		pOut->WriteElement(tag_CaretForeColor,info.CaretForeColor);
		pOut->WriteElement(tag_TabWidth,info.TabWidth);
		pOut->WriteElement(tag_Lexer,info.Lexer);
		pOut->WriteElement(tag_TriggerChars,info.TriggerChars);

		for (std::vector<EditColors>::iterator iter = info.ColorMap.begin();iter!=info.ColorMap.end();++iter) {
			EditColorsSerializer tmp(*iter);
			pOut->WriteSubElement(&tmp,attribs);
		}
		pOut->EndObject(tag_Own);
	}

	void MakeColors() {
		for (int i = 0;i<(int)pairs.size();++i) {
			info.ColorMap.push_back(pairs[i]->info);
			delete pairs[i];
			pairs[i] = NULL;
		}
	}
};

SXP::Tag ConfigInfoSerializer::tag_Extension("extension");
SXP::Tag ConfigInfoSerializer::tag_Font("font");
SXP::Tag ConfigInfoSerializer::tag_UseTabs("use_tabs");
SXP::Tag ConfigInfoSerializer::tag_Keywords("keywords");
SXP::Tag ConfigInfoSerializer::tag_Own("config_info");
SXP::Tag ConfigInfoSerializer::tag_CaretLineVisible("caret_line_visible");
SXP::Tag ConfigInfoSerializer::tag_CaretLineBack("caret_line_back");
SXP::Tag ConfigInfoSerializer::tag_BackColor("back_color");
SXP::Tag ConfigInfoSerializer::tag_ForeColor("fore_color");
SXP::Tag ConfigInfoSerializer::tag_CaretForeColor("caret_fore_color");
SXP::Tag ConfigInfoSerializer::tag_TabWidth("tab_width");
SXP::Tag ConfigInfoSerializer::tag_Lexer("lexer");
SXP::Tag ConfigInfoSerializer::tag_TriggerChars("trigger_chars");